// rulermanager.cpp
#include "ruler_manager.h"

namespace eintik::presentation::viewcore {

// 初始化静态旋转变换矩阵：依次对应0°/90°/180°/270°旋转
const QVector<QTransform> RulerManager::rotateForm = {
    QTransform(1, 0, 0, 0, 1, 0, 0, 0, 1),   // 0°旋转（原始状态）
    QTransform(0, 1, 0, -1, 0, 0, 0, 0, 1),  // 90°旋转
    QTransform(-1, 0, 0, 0, -1, 0, 0, 0, 1), // 180°旋转
    QTransform(0, -1, 0, 1, 0, 0, 0, 0, 1)   // 270°旋转
};

/**
 * @brief 构造函数：初始化父视图和标尺区域缓存
 * @param parent 父视图指针
 */
RulerManager::RulerManager(NdtScanView *parent)
    : QObject(parent)
    , m_parentView(parent)
{
    m_rulerRect.resize(2); // 缓存2个主要标尺（左/底）的几何区域
}

/**
 * @brief 初始化4个预设标尺，分别对应左/底/右1/右2位置
 * @details 每个标尺指定初始位置、类型，并关联父视图
 */
void RulerManager::initRulers()
{
    m_rulers = {
        // 左侧标尺：高度标尺
        new QRuleBar(QRulerPos::Left_Ruler, QRulerType::Height_Ruler, m_parentView, m_parentView),
        // 底部标尺：水平距离标尺
        new QRuleBar(QRulerPos::Bottom_Ruler, QRulerType::HDistance_Ruler, m_parentView,
                     m_parentView),
        // 右侧1标尺：颜色条标尺
        new QRuleBar(QRulerPos::Right_Ruler1, QRulerType::ColorBar_Ruler, m_parentView,
                     m_parentView),
        // 右侧2标尺：深度标尺
        new QRuleBar(QRulerPos::Right_Ruler2, QRulerType::Depth_Ruler, m_parentView, m_parentView),
    };
}

/**
 * @brief 设置指定标尺的数值范围和单位（仅对启用状态的标尺生效）
 * @param id 标尺索引
 * @param rulerStart 起始值
 * @param rulerEnd 结束值
 * @param unit 单位字符串
 */
void RulerManager::setRulerRange(int32_t id, double rulerStart, double rulerEnd,
                                 const QString &unit)
{
    if (id < 0 || id >= m_rulers.size())
        return;

    QRuleBar *ruler = m_rulers[id];
    if (ruler && ruler->RulerEnable()) {
        // 设置范围（第三个参数为最大值，用于刻度计算）
        ruler->setRange(rulerStart, rulerEnd,
                        fabs(rulerStart) > fabs(rulerEnd) ? rulerStart : rulerEnd);

        // 单位变化时更新单位
        if (!unit.isEmpty() && unit != ruler->getUnitStr()) {
            ruler->setUnitStr(unit);
        }
    }
}

/**
 * @brief 获取指定标尺的数值范围（仅对启用状态的标尺生效）
 * @param id 标尺索引
 * @param rulerStart 输出参数，起始值
 * @param rulerEnd 输出参数，结束值
 */
void RulerManager::getRulerRange(int32_t id, double &rulerStart, double &rulerEnd)
{
    rulerStart = 0.0;
    rulerEnd = 0.0;

    if (id < 0 || id >= m_rulers.size())
        return;

    QRuleBar *ruler = m_rulers[id];
    if (ruler && ruler->RulerEnable()) {
        double maxSize; // 临时变量，接收最大值（未使用）
        ruler->getRange(rulerStart, rulerEnd, maxSize);
    }
}

/**
 * @brief 为指定标尺设置颜色映射（主要用于颜色条标尺）
 * @param colorVector 颜色序列
 * @param id 标尺索引
 */
void RulerManager::setColorMap(const QVector<QColor> &colorVector, int32_t id)
{
    if (id >= 0 && id < m_rulers.size()) {
        m_rulers[id]->setColorMap(colorVector);
    }
}

void RulerManager::updateRulers()
{
    for (auto i = 0; i < 4; i++) {
        updateRuler(i);
    }
}

void RulerManager::updateRuler(int32_t id)
{
    if (id == -1) {
        for (int i = 0; i < RULER_CNT; i++) {
            m_rulers[i]->update();
        }
    } else {
        if ((id >= 0) && (id < RULER_CNT))
            m_rulers[id]->update();
    }
}

/**
 * @brief 根据旋转类型更新标尺的变换矩阵和位置
 * @param rotateType 旋转类型（0°/90°/180°/270°/垂直镜像）
 * @details 旋转时交换左/底标尺的逻辑位置，并应用对应的旋转变换
 */
void RulerManager::refreshRulerPosition(RotateType rotateType)
{
    QVector<QRuleBar *> tempRuler; // 临时存储需要旋转的标尺

    // 根据旋转类型选择参与旋转的标尺及顺序
    switch (rotateType) {
    case RotateType::R0:                          // 0°旋转
    case RotateType::V_Mirror:                    // 垂直镜像
        tempRuler.append(m_rulers[Left_Ruler]);   // 左侧标尺优先
        tempRuler.append(m_rulers[Bottom_Ruler]); // 底部标尺其次
        break;
    case RotateType::R90:                         // 90°旋转
        tempRuler.append(m_rulers[Bottom_Ruler]); // 底部标尺逻辑上变为左侧
        tempRuler.append(m_rulers[Left_Ruler]);   // 左侧标尺逻辑上变为底部
        break;
    case RotateType::R180: // 180°旋转
        tempRuler.append(m_rulers[Left_Ruler]);
        tempRuler.append(m_rulers[Bottom_Ruler]);
        break;
    case RotateType::R270: // 270°旋转
        tempRuler.append(m_rulers[Bottom_Ruler]);
        tempRuler.append(m_rulers[Left_Ruler]);
        break;
    }

    // 应用旋转变换并更新位置
    for (auto i = 0; i < tempRuler.size(); i++) {
        if (tempRuler.at(i) != nullptr && tempRuler.at(i)->RulerEnable()) {
            tempRuler.at(i)->setTransform(rotateForm[static_cast<int>(rotateType)]); // 设置旋转矩阵
            tempRuler.at(i)->setRulerPosition(static_cast<QRulerPos>(i)); // 更新逻辑位置
            tempRuler.at(i)->setGeometry(m_rulerRect[i]); // 应用缓存的几何区域
            tempRuler.at(i)->rotateNo = rotateType;       // 记录旋转状态
        }
    }
}

/**
 * @brief 调整标尺大小和位置（视图尺寸变化时调用）
 * @param viewWidth 视图宽度
 * @param viewHeight 视图高度
 * @param left 左边距参考值
 * @param right 右边距参考值
 * @param bottom 底边距参考值
 */
void RulerManager::resizeRulers(int viewWidth, int viewHeight, int left, int right, int bottom)
{
    // 更新左侧和底部标尺的几何区域缓存
    m_rulerRect[0] =
        QRect(0, 0, RULER_SIZE, viewHeight - bottom); // 左侧标尺：高度为视图高度减去底边距
    m_rulerRect[1] = QRect(left, viewHeight - bottom, viewWidth - left - right,
                           RULER_SIZE); // 底部标尺：宽度为视图宽度减去左右边距

    // 调整右侧1标尺（颜色条）
    if (m_rulers[Right_Ruler1]->RulerEnable()) {
        m_rulers[Right_Ruler1]->resize(RULER_SIZE / 2, viewHeight - bottom); // 宽度为标准尺寸的一半
        m_rulers[Right_Ruler1]->move(viewWidth - right, 0);                  // 定位到右侧
    }

    // 调整右侧2标尺
    if (m_rulers[Right_Ruler2]->RulerEnable()) {
        m_rulers[Right_Ruler2]->resize(RULER_SIZE, viewHeight - bottom); // 标准宽度
        m_rulers[Right_Ruler2]->move(viewWidth - RULER_SIZE, 0);         // 定位到最右侧
    }
}

/**
 * @brief 根据视图类型初始化标尺的类型、范围、单位和启用状态
 * @param type 视图类型（A_SCAN/S_SCAN/C_SCAN_0/C_SCAN_1）
 */
void RulerManager::initView(VIEW_TYPE type)
{
    if (type == VIEW_TYPE::A_SCAN) { // A扫描视图
        // 左侧标尺：高度标尺（0-100%）
        m_rulers[Left_Ruler]->setRulerType(Height_Ruler);
        m_rulers[Left_Ruler]->setRange(100, 0, 100);
        m_rulers[Left_Ruler]->setUnitStr("%");
        m_rulers[Left_Ruler]->setRulerEnable(true);
        m_rulers[Left_Ruler]->show();

        // 底部标尺：声程标尺（0-100mm）
        m_rulers[Bottom_Ruler]->setRulerType(SoundPath_Ruler);
        m_rulers[Bottom_Ruler]->setRulerEnable(true);
        m_rulers[Bottom_Ruler]->setUnitStr("mm");
        m_rulers[Bottom_Ruler]->setRange(0, 100, 100);
        m_rulers[Bottom_Ruler]->show();
    } else if (type == VIEW_TYPE::S_SCAN) { // S扫描视图
        // 左侧标尺：深度标尺
        m_rulers[Left_Ruler]->setRulerType(Depth_Ruler);
        m_rulers[Left_Ruler]->setRulerEnable(true);
        m_rulers[Left_Ruler]->show();

        // 底部标尺：水平距离标尺
        m_rulers[Bottom_Ruler]->setRulerType(HDistance_Ruler);
        m_rulers[Bottom_Ruler]->setRulerEnable(true);
        m_rulers[Bottom_Ruler]->show();

        // 右侧1标尺：颜色条标尺
        m_rulers[Right_Ruler1]->setRulerType(ColorBar_Ruler);
        m_rulers[Right_Ruler1]->setRulerEnable(true);
        m_rulers[Right_Ruler1]->show();

        // 右侧2标尺：高度标尺（0-100%）
        m_rulers[Right_Ruler2]->setRulerType(Height_Ruler);
        m_rulers[Right_Ruler2]->setRulerEnable(true);
        m_rulers[Right_Ruler2]->setRange(0, 100, 100);
        m_rulers[Right_Ruler2]->setUnitStr("%");
        m_rulers[Right_Ruler2]->show();
    } else if (type == VIEW_TYPE::C_SCAN_0 || type == VIEW_TYPE::C_SCAN_1) { // C扫描视图
        // 左侧标尺：高度标尺（支持缩放）
        m_rulers[Left_Ruler]->setRulerType(Height_Ruler);
        m_rulers[Left_Ruler]->setRulerEnable(true);
        m_rulers[Left_Ruler]->setZoomEnable(true);
        m_rulers[Left_Ruler]->show();

        // 底部标尺：扫描标尺（支持缩放）
        m_rulers[Bottom_Ruler]->setRulerType(Scan_Ruler);
        m_rulers[Bottom_Ruler]->setRulerEnable(true);
        m_rulers[Bottom_Ruler]->setZoomEnable(true);
        m_rulers[Bottom_Ruler]->show();

        // 右侧1标尺：颜色条标尺
        m_rulers[Right_Ruler1]->setRulerType(ColorBar_Ruler);
        m_rulers[Right_Ruler1]->setRulerEnable(true);
        m_rulers[Right_Ruler1]->show();

        // 右侧2标尺：高度标尺（支持缩放，0-100%）
        m_rulers[Right_Ruler2]->setRulerType(Height_Ruler);
        m_rulers[Right_Ruler2]->setRulerEnable(true);
        m_rulers[Right_Ruler2]->setZoomEnable(true);
        m_rulers[Right_Ruler2]->setRange(0, 100, 100);
        m_rulers[Right_Ruler2]->setUnitStr("%");
        m_rulers[Right_Ruler2]->show();
    }
}

/**
 * @brief 根据标尺启用状态计算视图边距
 * @param left 输出左边距（左侧标尺启用时为标准尺寸）
 * @param top 输出上边距（固定为0，无顶部标尺）
 * @param right 输出右边距（右侧1和右侧2标尺宽度之和）
 * @param bottom 输出底边距（底部标尺启用时为标准尺寸）
 */
void RulerManager::calculateMargins(int &left, int &top, int &right, int &bottom) const
{
    left = top = right = bottom = 0;

    if (m_rulers[Left_Ruler]->RulerEnable()) {
        left = RULER_SIZE; // 左侧标尺宽度为标准尺寸
    }

    if (m_rulers[Bottom_Ruler]->RulerEnable()) {
        bottom = RULER_SIZE; // 底部标尺高度为标准尺寸
    }

    if (m_rulers[Right_Ruler1]->RulerEnable()) {
        right += RULER_SIZE / 2; // 右侧1标尺宽度为标准尺寸的一半
    }

    if (m_rulers[Right_Ruler2]->RulerEnable()) {
        right += RULER_SIZE; // 右侧2标尺宽度为标准尺寸
    }
}

/**
 * @brief 获取指定索引的标尺指针
 * @param id 标尺索引
 * @return 有效索引返回标尺指针，否则返回nullptr
 */
QRuleBar *RulerManager::getRuler(int32_t id) const
{
    if (id >= 0 && id < m_rulers.size()) {
        return m_rulers[id];
    }
    return nullptr;
}

/**
 * @brief 检查指定标尺是否启用
 * @param id 标尺索引
 * @return 标尺存在且启用返回true，否则返回false
 */
bool RulerManager::isRulerEnabled(int32_t id) const
{
    QRuleBar *ruler = getRuler(id);
    return ruler ? ruler->RulerEnable() : false;
}

/**
 * @brief 析构函数：释放所有标尺对象并清空集合
 */
RulerManager::~RulerManager()
{
    qDeleteAll(m_rulers); // 批量删除所有标尺
    m_rulers.clear();     // 清空集合
}

}
